package visual_map

import (
	"errors"
	"cgs-server/server"
	"cgs-server/server/base"
	"cgs-server/server/model"
	"go.mongodb.org/mongo-driver/bson"
)

type MapRepository interface {
	base.Repository
}

func NewMapRepository() MapRepository {
	return &mapRepository{
		RepositoryStruct: base.RepositoryStruct{
			CollectionName: server.CgsPortalMapCollectionName,
		},
	}
}

type mapRepository struct {
	base.RepositoryStruct
}

func (m *mapRepository) Find(mdl *model.DataUserModel) (interface{}, error) {
	if visualMap, ok := mdl.Data.(*Map); ok {
		if err := m.CheckDB(); err != nil {
			return nil, err
		}
		filter := bson.M{}
		visualMap.ResolveFilter(visualMap, mdl.User, &filter)
		opts := visualMap.ResolveOptions(mdl.Page)
		result := []*Map{}
		err := m.Mongo.FindMany(m.CollectionName, filter, &result, opts)
		return result, err
	} else {
		return nil, model.NewTypeError("VisualMap")
	}
}

func (m *mapRepository) Insert(mdl *model.DataUserModel) error {
	if visualMap, ok := mdl.Data.(*Map); ok {
		if err := m.CheckDB(); err != nil {
			return err
		}
		visualMap.ResolveEntity(visualMap, mdl.User)
		_, err := m.Mongo.InsertOne(m.CollectionName, visualMap)
		return err
	} else {
		return model.NewTypeError("VisualMap")
	}
}

func (m *mapRepository) Update(mdl *model.DataUserModel) error {
	if visualMap, ok := mdl.Data.(*Map); ok {
		if err := m.CheckDB(); err != nil {
			return err
		}
		filter := bson.M{
			"id": visualMap.Id,
		}
		visualMap.ResolveFilter(visualMap, mdl.User, &filter)

		updateOpt := bson.M{}
		if visualMap.Name != "" {
			updateOpt["name"] = visualMap.Name
		}
		if visualMap.Data != "" {
			updateOpt["data"] = visualMap.Data
		}
		visualMap.ResolveUpdateCondition(visualMap, mdl.User, &updateOpt)
		update := bson.M{"$set": updateOpt}

		_, err := m.Mongo.UpdateOne(m.CollectionName, filter, update)
		return err
	} else {
		return model.NewTypeError("VisualMap")
	}
}

func (m * mapRepository) Delete(mdl *model.DataUserModel) error {
	if visualMap, ok := mdl.Data.(*Map); ok {
		if err := m.CheckDB(); err != nil {
			return err
		}
		filter := bson.M{"id": visualMap.Id}
		visualMap.ResolveFilter(visualMap, mdl.User, &filter)
		_, err := m.Mongo.DeleteOne(m.CollectionName, filter)
		return err
	} else {
		return model.NewTypeError("VisualMap")
	}
}

func (m *mapRepository) FindOne(mdl *model.DataUserModel) (interface{}, error) {
	if visualMap, ok := mdl.Data.(*Map); ok {
		if err := m.CheckDB(); err != nil {
			return nil, err
		}
		filter := bson.M{"id": visualMap.Id}
		visualMap.ResolveFilter(visualMap, mdl.User, &filter)
		res := &Map{}
		find, err := m.Mongo.FindOne(m.CollectionName, filter, res)
		if !find {
			return nil, errors.New("not found")
		}
		return res, err
	} else {
		return nil, model.NewTypeError("VisualMap")
	}
}
